package com.tanhua.app.Service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.CommentVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CommentsService {
    @DubboReference
    private CommentApi commentApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserFreezeService userFreezeService;
    @Autowired
    private MqMessageService mqMessageService;

    //    评论列表
    public PageResult findComments(String movementId, Integer page, Integer pageSize) {
        List<Comment> commentList = commentApi.findComments(movementId, CommentType.COMMENT, page, pageSize);
        if (CollUtil.isEmpty(commentList)) {
            return new PageResult(page, pageSize, 0, null);
        }
        List<Long> userId = CollUtil.getFieldValues(commentList, "userId", Long.class);
        List<UserInfo> userInfos = userInfoApi.findByUserIds(userId);
        Map<Long, UserInfo> map = userInfos.stream()
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        List<CommentVo> vos = new ArrayList<>();
        for (Comment comment : commentList) {
            UserInfo userInfo = map.get(comment.getUserId());
            if (userInfo != null) {
                CommentVo init = CommentVo.init(userInfo, comment);
                String key = Constants.MOVEMENTS_RECOMMEND+comment.getId().toHexString();
                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
                if(redisTemplate.opsForHash().hasKey(key,hashKey)){
                    init.setHasLiked(1);
                }
                vos.add(init);
            }
        }
        return new PageResult(page, pageSize, 0, vos);
    }

    //    评论提交
    public void saveComments(String movementId, String comment) {
        Long userId = UserHolder.getUserId();
        if (userId != null) {
            userFreezeService.checkUserFreeze(userId,"2");
        }
        Comment newComment = new Comment();
        newComment.setCommentType(CommentType.COMMENT.getType());
        newComment.setContent(comment);
        newComment.setPublishId(new ObjectId(movementId));
        newComment.setUserId(userId);
        newComment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.save(newComment);
        mqMessageService.sendLogMessage(userId,"0205","movement",movementId);
    }

    //    动态点赞
    public Integer likeMovement(String movementId) {
        Long userId = UserHolder.getUserId();
        boolean hasLike = commentApi.hasMovement(movementId, userId, CommentType.LIKE);
        if (hasLike) {
            throw new BusinessException(ErrorResult.likeError());
        }

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.save(comment);

        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + userId;
        redisTemplate.opsForHash().put(key, hashKey, "1");
        mqMessageService.sendLogMessage(userId,"0203","movement",movementId);

        return count;
    }

    //    动态-取消点赞
    public Integer dislikeMovement(String movementId) {
        Long userId = UserHolder.getUserId();
        boolean hasComment = commentApi.hasMovement(movementId, userId, CommentType.LIKE);
        if (!hasComment) {
            throw new BusinessException(ErrorResult.disLikeError());
        }

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setPublishId(new ObjectId(movementId));
        Integer count = commentApi.remove(comment);
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + userId;
        redisTemplate.opsForHash().delete(key, hashKey);
        mqMessageService.sendLogMessage(userId,"0206","movement",movementId);
        return count;
    }

    //    动态-喜欢
    public Integer loveMovement(String movementId) {
        Long userId = UserHolder.getUserId();
        boolean hasComment = commentApi.hasMovement(movementId, userId, CommentType.LOVE);
        if (hasComment) {
            throw new BusinessException(ErrorResult.loveError());
        }

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.save(comment);

        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + userId;
        redisTemplate.opsForHash().put(key, hashKey, "1");
        mqMessageService.sendLogMessage(userId,"0204","movement",movementId);

        return count;
    }

    //    动态-取消喜欢
    public Integer unlove(String movementId) {
        Long userId = UserHolder.getUserId();
        boolean hasComment = commentApi.hasMovement(movementId, userId, CommentType.LOVE);
        if (!hasComment) {
            throw new BusinessException(ErrorResult.disloveError());
        }

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setPublishId(new ObjectId(movementId));
        Integer count = commentApi.remove(comment);
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + userId;
        redisTemplate.opsForHash().delete(key, hashKey);
        mqMessageService.sendLogMessage(userId,"0207","movement",movementId);
        return count;
    }

    //    评论-点赞
    public Integer likeComments(String commentId) {
        Long userId = UserHolder.getUserId();
        boolean hasLike = commentApi.hasMovement(commentId, userId, CommentType.LIKE);
        if (hasLike) {
            throw new BusinessException(ErrorResult.likeError());
        }

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(commentId));
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.updateComment(comment);

        String key = Constants.MOVEMENTS_RECOMMEND + commentId;
        String hashKey = Constants.COMMENTS_LIKE_HASHKEY + userId;
        redisTemplate.opsForHash().put(key, hashKey, "1");

        return count;
    }

    //    评论-取消点赞
    public Integer dislikeComments(String commentId) {
        Long userId = UserHolder.getUserId();
        boolean hasComment = commentApi.hasMovement(commentId, userId, CommentType.LIKE);
        if (!hasComment) {
            throw new BusinessException(ErrorResult.disLikeError());
        }

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setPublishId(new ObjectId(commentId));
        Integer count = commentApi.removeComment(comment);
        String key = Constants.MOVEMENTS_RECOMMEND + commentId;
        String hashKey = Constants.COMMENTS_LIKE_HASHKEY + userId;
        redisTemplate.opsForHash().delete(key, hashKey);
        return count;
    }
}
